#include <windows.h>

#include "lib.h"
#include "pathname.h"
#include "stream.h"

#include "casino.h"
#include "event.h"

#include "pkgmgr.h"
#include "apppath.h"
#include "msgbox.h"
#include "winapp.h"
#include "zipfile.h"
#include "dir.h"

bool8
PackageMgr::installRSyncLobby(Package *pkg, bool8 showMessage)
{
	PathName src, dest;

	if (!src.set(AppPath::getExeDir()) 		||
		!src.concat("_patch")				||
		!src.concat("Lobby")				||
		!src.concat("lbyinst.exe") 			||

		!dest.set(AppPath::getTempDir()) 	||
		!dest.concat("lbyinst.exe") 		||

		!CopyFile(src, dest, FALSE))
		return false;

	SetFileAttributes(dest, FILE_ATTRIBUTE_NORMAL);

	if (showMessage)
		MsgBox::show(m_app, CApp::getString("PkgInstallLobbyTitle"),
			CApp::getString("PkgInstallLobbyMsg"),
			MsgBox::OK | MsgBox::ICONINFO);

	// we have a lobby install AND this is a rsync install
	((CWinApp*)m_app)->setInstallSelf(true, true);

	m_app->queueEvent(new Event(Event::STOP_APP));

	return true;
}

bool8
PackageMgr::unzipLbyInst()
{
	ZipEntry* ze;
	pCStream out = (pCStream)0;
	UnzipStream* uzs = (UnzipStream*)0;
	int32 amt, origDestLen=0;
	uint8 buf[4096];

	PathName src, Dest;
	PathName zipfile;

	ZipFile ZF;

	// set where our lobby.zip is located
	if(!zipfile.set(AppPath::getExeDir())  ||
       !zipfile.concat("lobby.zip"))
	{
		goto abort;
	}

	// open it up
	if(!ZF.open(zipfile))
		goto abort;

	// set it's destination 
	if(!Dest.set(AppPath::getTempDir()))
    {
		goto abort;
	}

	origDestLen = Dest.getLen();

	ze = ZF.getZipEntries();
	while (ze)
	{
		if(ze->filename.caseCompare("lbyinst.exe") == 0)
		{
			if(ze->isFilenameValid() && !ze->isEncrypted())
			{
				if (!Dest.concat(ze->filename))
					goto abort;

				// change unix separators (stored in zipfile)
				//
				Dest.replace('/', Directory::sep);

				if (ze->isDirectory())
				{
					if (!Directory::makeAll(Dest))
						goto abort;
				}
				else
				{
					if (!Directory::makeAll(Dest, Directory::EndIsFilename))
						goto abort;

					out = newCStream(Dest, streamO_WRONLY);
					if (!out)
						goto abort;

					uzs = ze->getUnzipStream(&ZF);
					if (uzs)
					{
						while ((amt = uzs->read(buf, 4096)) >= 0)
						{
							if (amt > 0 && amt != CStreamWrite(out, buf, amt))
							{
								amt = -2;
								break;
							}
						}

						if (amt < -1)
							goto abort;

						deleteCStream(out);
						delete uzs;
						out = (pCStream)0;
						uzs = (UnzipStream*)0;
					}
					else
						goto abort;
				}

				Dest.shrink(Dest.getLen() - origDestLen);
			}
			else
				goto abort;
		}
		ze = ze->getNext();
	}

	ZF.close();
	return true;

abort:
	ZF.close();
	delete uzs;
	deleteCStream(out);
	Dest.shrink(Dest.getLen() - origDestLen);

	return false;

}

bool8
PackageMgr::copyLbyInst()
{
	PathName src, dest;
	if(!src.set(AppPath::getTempDir())		||
	   !src.concat("Lobby")				||
	   !src.concat("lbyinst.exe") 			||
	   !dest.set(AppPath::getTempDir()) 	||
	   !dest.concat("lbyinst.exe") 		||
	   !CopyFile(src, dest, FALSE))
	{
		return false;
	}

	return true;
}

bool8
PackageMgr::installLobby(Package* Pkg, const PathName& ZipFilename)
{

	// try to unzip lbyinst from the lobby zip file first, then if
	//  that fails, simply copy the existing lbyinst.exe over to the
	//  temp directory
	if(!unzipLbyInst())
	{
		if(!copyLbyInst())
			return false;
	}

	MsgBox::show(m_app, CApp::getString("PkgInstallLobbyTitle"),
		CApp::getString("PkgInstallLobbyMsg"),
		MsgBox::OK | MsgBox::ICONINFO);
	((CWinApp*)m_app)->setInstallSelf(true);

	m_app->queueEvent(new Event(Event::STOP_APP));

	return true;
}

void
PackageMgr::installGameHelp(Package* /*Pkg*/)
{
	PathName hlpgid;

	// make sure game's help file shows up in the master help
	//
	if (hlpgid.set(AppPath::getExeDir()) &&
		hlpgid.concat("help") &&
		hlpgid.concat("top.gid"))
		CStreamDelFile(hlpgid);
}
